package tools

import (
	//"finance_admin/tool/Logger"
	"reflect"
	"sort"
	"strconv"
)

// SliceTools /**
type SliceTools struct {
}

// SliceToolsObject /**
var SliceToolsObject SliceTools

// InArray 查找字符是否在数组中
func (SliceTools) InArray(obj interface{}, target interface{}) bool {
	targetValue := reflect.ValueOf(target)
	switch reflect.TypeOf(target).Kind() {
	case reflect.Slice, reflect.Array:
		for i := 0; i < targetValue.Len(); i++ {
			if targetValue.Index(i).Interface() == obj {
				return true
			}
		}
	case reflect.Map:
		if targetValue.MapIndex(reflect.ValueOf(obj)).IsValid() {
			return true
		}
	}
	return false
}

/**
*  GetKeys
*  @Description: 获取map的key对应的
*  @receiver receiver
*  @param mapParams
*  @return []string
 */

func (receiver *SliceTools) ColumnBySlice(mapParams []map[string]interface{}, keyParams string) []interface{} {
	slice := make([]interface{}, 0)
	for _, value := range mapParams {
		//判断key是否存在
		if val, ok := value[keyParams]; !ok {
			//Logger.LoggersToolsObject.PanicAndLog("ColumnBySlice.37", "此key不存在")
		} else {
			slice = append(slice, val)
		}
	}
	return slice
}

/**
 *  inSlice
 *  @Description: 判断字符串是否在字符串切片中
 *  @receiver receiver
 *  @param mapParams
 *  @param keyParams
 *  @return bool
 */

func (receiver *SliceTools) InSliceString(keyParams string, sliceParams []string) bool {
	for _, e := range sliceParams {
		if e == keyParams {
			return true
		}
	}
	return false
}

/**
 *  GetIntersection
 *  @Description: 求交集
 *  @receiver receiver
 *  @param sliceParams1
 *  @param sliceParams2
 *  @return []string
 */

func (receiver *SliceTools) GetIntersection(sliceParams1 []string, sliceParams2 []string) []string {
	intersection := make([]string, 0)
	//获取两个参数的长度
	len1 := len(sliceParams1)
	len2 := len(sliceParams2)
	if 0 == len1 || 0 == len2 {
		return intersection
	}
	tmpLen := 0
	tmpShort := 0
	if len2 >= len1 {
		tmpLen = len2
		tmpShort = len1
	} else {
		tmpLen = len1
		tmpShort = len2
	}
	lenSliceParams := make([]string, tmpLen)
	shortSliceParams := make([]string, tmpShort)
	if len2 >= len1 {
		copy(lenSliceParams, sliceParams2)
		copy(shortSliceParams, sliceParams1)
	} else {
		copy(lenSliceParams, sliceParams1)
		copy(shortSliceParams, sliceParams2)
	}
	tmpMap := make(map[string]string)
	for key, value := range shortSliceParams {
		tmpMap[value] = strconv.Itoa(key)
	}
	//判断key是否存在
	for i := 0; i < tmpLen; i++ {
		item := sliceParams1[i]
		if _, ok := tmpMap[item]; ok {
			intersection = append(intersection, item)
		}
	}
	return intersection
}

/**
 *  ToSliceString
 *  @Description: []interface{} 转为 []string
 *  @receiver receiver
 *  @param params
 *  @return []string
 */

func (receiver SliceTools) ToSliceStringByInterface(params []interface{}) []string {
	strings := make([]string, 0)
	for _, value := range params {
		strings = append(strings, InterfaceToolsObject.ToString(value))
	}
	return strings
}

/**
 *  ToSliceString
 *  @Description: []interface{} 转为 []string
 *  @receiver receiver
 *  @param params
 *  @return []string
 */

func (h SliceTools) ToSliceStringByInt(params []int) []string {
	strings := make([]string, 0)
	for _, value := range params {
		strings = append(strings, InterfaceToolsObject.ToString(value))
	}
	return strings
}

/**
 *  DifferenceSliceByString
 *  @Description: 如果在A中不在B中，如果在B中但是不在A中的数据集合
 *  @receiver h
 *  @param sliceOne
 *  @param sliceTwo
 *  @return []string
 */

func (h SliceTools) DifferenceSliceByString(sliceOne []string, sliceTwo []string) []string {
	differ := make([]string, 0)
	if len(sliceOne) == 0 && len(sliceTwo) == 0 {
		return differ
	}
	mapOne := make(map[string]string)
	mapTwo := make(map[string]string)
	for _, i2 := range sliceOne {
		mapOne[i2] = i2
	}
	for _, i3 := range sliceTwo {
		mapTwo[i3] = i3
	}
	for i, _ := range mapOne {
		_, isHas := mapTwo[i]
		if !isHas {
			differ = append(differ, i)
		}
	}
	for i, _ := range mapTwo {
		_, isHas := mapOne[i]
		if !isHas {
			differ = append(differ, i)
		}
	}
	return differ
}

// 求差集 slice1-并集
// 差集：以属于slice1而不属于slice2的元素为元素的集合成为slice1与slice2的差（集）

func (h SliceTools) Difference(slice1, slice2 []string) []string {
	m := make(map[string]int)
	nn := make([]string, 0)
	inter := h.GetIntersection(slice1, slice2)
	for _, v := range inter {
		m[v]++
	}
	for _, value := range slice1 {
		times, _ := m[value]
		if times == 0 {
			nn = append(nn, value)
		}
	}
	return nn
}

// 切片去重

func (h SliceTools) RemoveDuplicateElement(languages []string) []string {
	result := make([]string, 0, len(languages))
	temp := map[string]struct{}{}
	for _, item := range languages {
		if _, ok := temp[item]; !ok { //如果字典中找不到元素，ok=false，!ok为true，就往切片中append元素。
			temp[item] = struct{}{}
			result = append(result, item)
		}
	}
	return result
}

// 切片去重

func (h SliceTools) RemoveDuplicateElementLongInt(languages []int64) []int64 {
	result := make([]int64, 0, len(languages))
	temp := map[int64]struct{}{}
	for _, item := range languages {
		if _, ok := temp[item]; !ok { //如果字典中找不到元素，ok=false，!ok为true，就往切片中append元素。
			temp[item] = struct{}{}
			result = append(result, item)
		}
	}
	return result
}

// 查出新增的，和删除的

func (h SliceTools) GetAddAndDelete(old []int64, new []int64) ([]int64, []int64) {
	oldMap := make(map[int64]int64)
	newMap := make(map[int64]int64)
	//旧的map
	for _, i2 := range old {
		oldMap[i2] = i2
	}
	//新的map
	for _, i2 := range new {
		newMap[i2] = i2
	}
	//todo 新的有，老的没有，是新增的
	add := make([]int64, 0)
	for _, i2 := range newMap {
		if _, ok := oldMap[i2]; !ok {
			add = append(add, i2)
		}
	}
	//todo 老的有，新的没有，是删除的
	deleteTmp := make([]int64, 0)
	for _, i2 := range oldMap {
		if _, ok := newMap[i2]; !ok {
			deleteTmp = append(deleteTmp, i2)
		}
	}
	//新的有，老的有，是不需要处理的
	return add, deleteTmp
}

// 插入排序

func (h SliceTools) InsertionSort(arr []int64) {
	for i := 1; i < len(arr); i++ {
		value := arr[i]
		for j := i - 1; j >= 0; j-- {
			if value < arr[j] {
				arr[j+1], arr[j] = arr[j], value
			} else {
				break
			}

		}
	}
}

//goland:noinspection GoMixedReceiverTypes
func (h SliceTools) DeleteEmptyAndUnique(arr []string) []string {
	tmpMap := make(map[string]string, 0)
	tmpString := make([]string, 0)
	for _, s := range arr {
		if s != "" {
			tmpMap[s] = s //去重和过滤
		}
	}
	for _, s2 := range tmpMap {
		tmpString = append(tmpString, s2)
	}
	return tmpString
}

// 切片int 升序
func (h SliceTools) SliceIntAsc(arr []int) []int {
	sort.Slice(arr, func(i, j int) bool {
		return arr[i] < arr[j]
	})
	return arr
}

// 切片int 升序
func (h SliceTools) SliceIntDesc(arr []int) []int {
	sort.Slice(arr, func(i, j int) bool {
		return arr[i] > arr[j]
	})
	return arr
}
